package com.duguo.dynamicmvc.factory.processor.model;

import java.util.Map;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.duguo.dynamicmvc.factory.ControllerFactory;
import com.duguo.dynamicmvc.support.pathinfo.PathInfo;

class ModelParameterCreatorImpl implements ModelParameterCreator{	


	public Object getParameterResolver(ControllerFactory controllerFactory, String paramName) throws Exception {
		if(controllerFactory.getWorkingModel().getParameterResolvers()!=null){
			if(controllerFactory.getWorkingModel().getParameterResolvers().containsKey(paramName))
				return controllerFactory.getWorkingModel().getParameterResolvers().get(paramName);
		}
		if(controllerFactory.getWorkingModel().isRootController()){
			if(controllerFactory.getControllerBuilder().getGloableParameterResolvers()!=null){
				if(controllerFactory.getControllerBuilder().getGloableParameterResolvers().containsKey(paramName))
					return controllerFactory.getControllerBuilder().getGloableParameterResolvers().get(paramName);
			}
		}else{
			return getParameterResolver(controllerFactory.getWorkingModel().getParentWorkModel().getControllerFactory(), paramName);
		}
		return null;
	}
	

	public String getParameterNameInRequest(CtClass modelImplCtClass, String fieldName, CtClass fieldType, ModelAnnotationReader modelAnnotationReader) throws Exception {
		String annoFieldName=modelAnnotationReader.getParameterName(modelImplCtClass,fieldName,fieldType);
		if(annoFieldName!=null)
			return annoFieldName;
		else
			return fieldName;
	}

	public String getNewUsedParamString(Map<String, CtClass> usedParams) {
		String usedParamStr="";
		for(String currentParam:usedParams.keySet()){
			if(usedParamStr.length()>0)
				usedParamStr+=",";
			usedParamStr+=usedParams.get(currentParam).getName()+" "+currentParam;
		}
		return usedParamStr;
	}

	public String getNewRequestParamName(Map<String,CtClass> usedParams,CtMethod controllerMethod) throws Exception {
		return getNewParamName(ClassPool.getDefault().get(HttpServletRequest.class.getName()),usedParams,controllerMethod,false);		
	}


	public String getNewResponseParamName(Map<String,CtClass> usedParams,CtMethod controllerMethod) throws Exception {
		return getNewParamName(ClassPool.getDefault().get(HttpServletResponse.class.getName()),usedParams,controllerMethod,false);		
	}


	public String getNewPathInfoName(Map<String,CtClass> usedParams,CtMethod controllerMethod) throws Exception {
		return getNewParamName(ClassPool.getDefault().get(PathInfo.class.getName()),usedParams,controllerMethod,false);		
	}
	
	public String getNewParamName(CtClass paramCtClass,Map<String,CtClass> usedParams,CtMethod controllerMethod,boolean ignoreNotFound) throws Exception {
		if(usedParams.containsValue(paramCtClass)){
			for(String paramName:usedParams.keySet()){
				if(usedParams.get(paramName)==paramCtClass)
					return paramName;
			}
		}
		
		int position=1;
		for(CtClass currentParam:controllerMethod.getParameterTypes()){
			if(paramCtClass==currentParam){
				String paramName="param"+position;
				usedParams.put(paramName, currentParam);
				return paramName;
			}
			position++;
		}
		if(!ignoreNotFound)
			throw new RuntimeException("Cannot find "+paramCtClass.getName()+" in the controllerMethod "+controllerMethod.getName()+"."+controllerMethod.getName());
		else
			return null;
	}
}
